package com.hb.trade.api.routine.controller.project.clarify;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import com.hb.core.pojo.Attachments;
import com.hb.core.pojo.JSONObjectProperty;
import com.hb.core.pojo.center.au.dto.OrgDTO;
import com.hb.core.pojo.enums.NewsTypeEnum;
import com.hb.core.pojo.enums.NewsTypeTwoEnum;
import com.hb.core.pojo.enums.SmsTypeEnum;
import com.hb.core.pojo.parent.PageResult;
import com.hb.core.pojo.project.section.dto.ClarifyConfirmDTO;
import com.hb.core.pojo.project.section.dto.ClarifyDTO;
import com.hb.core.pojo.project.section.dto.ClarifyTemplateDTO;
import com.hb.core.pojo.project.section.dto.ProblemDTO;
import com.hb.core.pojo.project.section.entity.ClarifySection;
import com.hb.core.pojo.project.section.entity.Problem;
import com.hb.trade.api.routine.controller.util.HTMLToPDFService;
import com.hb.trade.api.routine.sms.annotation.SmsSend;
import com.hb.trade.api.routine.util.SendNewsUtil;
import com.hb.trade.client.center.FileClient;
import com.hb.trade.client.center.NewsCenterClient;
import com.hb.trade.client.center.OrgClient;
import com.hb.trade.client.center.UserClient;
import com.hb.trade.client.project.ClarifyClient;
import com.hb.trade.client.project.ProjectClient;
import com.hb.trade.client.project.SectionClient;
import fzzn.core.aspose.convert.AsposeConvertUtil;
import fzzn.core.spire.OfficeUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.fzzn.core.auth.shiro.util.ShiroUtil;
import org.fzzn.core.file.entity.HbFileInfo;
import org.fzzn.core.file.entity.UploadEntity;
import org.fzzn.core.file.service.PersistenceService;
import org.fzzn.core.model.constant.CommonConstant;
import org.fzzn.core.model.enums.MsgEnum;
import org.fzzn.core.model.msg.Message;
import org.fzzn.core.model.msg.ResponseDto;
import org.fzzn.core.model.user.login.LoginUser;
import org.fzzn.core.third.sms.service.SmsService;
import org.fzzn.core.util.ResultUtil;
import org.fzzn.core.web.anno.Version;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.File;
import java.io.IOException;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 招标文件澄清
 *
 * @author Lix1ang
 * @date 2021-12-8 15:58:02
 */
@Slf4j
@Version(1.0)
@Api(tags = {"招标文件澄清"})
@RequestMapping("/{version}")
@RestController
public class ApiClarifyController {

    protected final RedisTemplate redisTemplate;
    protected final ClarifyClient clarifyClient;
    protected final PersistenceService persistenceService;
    protected final SectionClient sectionClient;
    protected final NewsCenterClient newsCenterClient;
    protected final ProjectClient projectClient;
    protected final UserClient userClient;
    protected final FileClient fileClient;
    protected final SmsService smsService;
    protected final OrgClient orgClient;

    public ApiClarifyController(RedisTemplate redisTemplate, ClarifyClient clarifyClient,
                                PersistenceService persistenceService,
                                SectionClient sectionClient,
                                NewsCenterClient newsCenterClient,
                                ProjectClient projectClient,
                                FileClient fileClient,
                                UserClient userClient, SmsService smsService, OrgClient orgClient) {
        this.redisTemplate = redisTemplate;
        this.clarifyClient = clarifyClient;
        this.persistenceService = persistenceService;
        this.sectionClient = sectionClient;
        this.newsCenterClient = newsCenterClient;
        this.projectClient = projectClient;
        this.userClient = userClient;
        this.fileClient = fileClient;
        this.smsService = smsService;
        this.orgClient = orgClient;
    }

    @ApiOperation(value = "保存澄清/补疑", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "ClarifyVO", value = "ClarifyVO", dataTypeClass = ClarifyDTO.class)
    })
    @PostMapping("/clarify/saveClarify")
    public ResponseDto saveClarify(@RequestBody ClarifyDTO clarify) {
        LoginUser<Long> loginUser = ShiroUtil.getUser();
        if (null == loginUser) {
            return ResultUtil.fail(MsgEnum.LOGIN_EXPIRE);
        }
        clarify.setTenderId(loginUser.getId());
        clarify.setProposerId(loginUser.getId());
        clarify.setProposerName(loginUser.getFullName());
        clarify.setProposerTime(LocalDateTime.now());

        // 保存附件
//        FileRecord fileRecord = new FileRecord();
//        fileRecord.buildBaseData(1);
//        String fileName = IdUtil.getIdStr();
//        fileRecord.setFileName(fileName);
//        Attachments attachments = clarify.getClarifyFileSignature();
//        for (Attachment attachment: attachments){
//            attachment.setFileName(fileName);
//            fileRecord.setRawFileName(attachment.getRawFileName());
//            fileRecord.setExtName(attachment.getExtName());
//            fileRecord.setFilePath(attachment.getFilePath());
//            fileRecord.setFileUrl(attachment.getFileUrl());
//        }
//        fileClient.saveFile(fileRecord);


        Message<ClarifyDTO> result = clarifyClient.saveClarify(clarify);
        if (result.isSuccess() && clarify.getBidOpeningTime() != null) {
            List<ClarifySection> sectionList = clarify.getSectionList();
            for (ClarifySection clarifySection : sectionList) {
                Long sectionId = clarifySection.getSectionId();
                String key = sectionId + "&" + SmsTypeEnum.OPENING.getCode();
                LocalDateTime openBidTime = clarify.getBidOpeningTime();

                long time = Timestamp.valueOf(openBidTime).getTime();
                time = time - System.currentTimeMillis() - (24 * 60 * 60 * 1000);
                // 如果小于24小时 则立即发送短信
                if (time > 0) {
                    redisTemplate.delete(key);
                    redisTemplate.opsForValue().set(key, Long.toString(sectionId), time, TimeUnit.MILLISECONDS);
                } else {
                    redisTemplate.delete(key);
                    redisTemplate.opsForValue().set(key, Long.toString(sectionId), 5, TimeUnit.MILLISECONDS);
                }
            }
        }

        // 之前是先保存在发布，现在直接发布所以将发送消息模块复制到保存接口。
        //给投标人发送消息
        if (result.getData() == null) {
            return ResultUtil.msg(result);
        }
        if (result.getData().getId() == null) {
            return ResultUtil.msg(result);
        }
        Message<ClarifyDTO> clarifyMessage = clarifyClient.findClarifyById(result.getData().getId());
        if (clarifyMessage.isFail() || clarifyMessage.getData() == null) {
            return ResultUtil.msg(result);
        }

        ClarifyDTO clarifyDTO = clarifyMessage.getData();
        if (CollUtil.isEmpty(clarifyDTO.getSectionList())) {
            return ResultUtil.msg(result);
        }
        List<ClarifySection> sectionList = clarifyDTO.getSectionList();
        for (ClarifySection clarifySection : sectionList) {
            Message<List<Long>> longUserIds = sectionClient.listParticipateSection(clarifySection.getSectionId());
            List<Long> receiverIds = longUserIds.getData();

            //给投标人发消息
            SendNewsUtil.sendBiddereeNews(
                    clarifySection.getSectionId(),
                    NewsTypeEnum.OBJECTION_QUESTION,
                    NewsTypeTwoEnum.BIDDER_OBJECTION,
                    null,
                    null,
                    "/console/clarify/bidder",
                    receiverIds
            );

        }
        return ResultUtil.msg(result);
//        return ResultUtil.msg(clarifyClient.saveClarify(clarify));
    }

    @ApiOperation(value = "招标人查询澄清/补疑列表", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "标段id", value = "sectionId", dataTypeClass = Long.class)
    })
    @PostMapping("/clarify/findClarifyList")
    public ResponseDto findClarifyList(@RequestBody ClarifyDTO clarifyDTO) {
        return ResultUtil.msg(clarifyClient.findClarifyList(clarifyDTO));
    }

    @ApiOperation(value = "澄清补遗签章", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "主键Id", value = "id", dataTypeClass = Long.class),
            @ApiImplicitParam(name = "澄清/补疑文件(签章)", value = "clarifyFileSignature", dataTypeClass = Attachments.class)
    })
    @PostMapping("/clarify/signature")
    public ResponseDto signature(@RequestBody ClarifyDTO clarifyDTO) {
        return ResultUtil.msg(clarifyClient.signature(clarifyDTO));
    }

    @ApiOperation(value = "招标人发出澄清/补疑", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "id", dataTypeClass = Long.class)
    })
    @PostMapping("/clarify/sendClarify")
    public ResponseDto sendClarify(@RequestBody ClarifyDTO clarifyDTO) {
        Long id = clarifyDTO.getId();
        if (id == null) {
            return ResultUtil.msg(MsgEnum.INCORRECT_PARAM);
        }
        Message message = clarifyClient.sendClarify(id);
        if (message.isFail()) {
            return ResultUtil.msg(message);
        }

        //给投标人发送消息
        Message<ClarifyDTO> clarifyMessage = clarifyClient.findClarifyById(id);
        if (clarifyMessage.isFail() || clarifyMessage.getData() == null) {
            return ResultUtil.msg(message);
        }
        ClarifyDTO clarify = clarifyMessage.getData();
        if (CollUtil.isEmpty(clarify.getSectionList())) {
            return ResultUtil.msg(message);
        }
        List<ClarifySection> sectionList = clarify.getSectionList();
        for (ClarifySection clarifySection : sectionList) {
            Message<List<Long>> longUserIds = sectionClient.listParticipateSection(clarifySection.getSectionId());
            List<Long> receiverIds = longUserIds.getData();

            //给投标人发消息
            SendNewsUtil.sendBiddereeNews(
                    clarifySection.getSectionId(),
                    NewsTypeEnum.OBJECTION_QUESTION,
                    NewsTypeTwoEnum.BIDDER_OBJECTION,
                    null,
                    null,
                    "/console/clarify/bidder",
                    receiverIds
            );

        }
        return ResultUtil.msg(message);
    }

    @ApiOperation(value = "投标人查询澄清/补疑列表", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "标段id", value = "sectionId", dataTypeClass = Long.class)
    })
    @PostMapping("/clarify/findBidderClarifyList")
    public ResponseDto findBidderClarifyList(@RequestBody ClarifyDTO clarifyDTO) {
        LoginUser<Long> loginUser = ShiroUtil.getUser();
        if (null == loginUser) {
            return ResultUtil.fail(MsgEnum.LOGIN_EXPIRE);
        }
        clarifyDTO.setTenderId(loginUser.getId());
        Message<PageResult<ClarifyDTO>> bidderClarifyList = clarifyClient.findBidderClarifyList(clarifyDTO);
        return ResultUtil.msg(bidderClarifyList);
    }

    @ApiOperation(value = "投标人确认", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "标段id", value = "sectionId", dataTypeClass = Long.class)
    })
    @PostMapping("/clarify/confirmClarify")
    public ResponseDto confirmClarify(@RequestBody ClarifyConfirmDTO clarifyConfirm) {
         if (clarifyConfirm.getSectionId() == null){
             return ResultUtil.fail("标段id并不能为空");
         }
        if (null == clarifyConfirm.getClarifyId()) {
            return ResultUtil.fail("澄清ID不允许为空");
        }
        ShiroUtil.fillOwner(clarifyConfirm);
        clarifyConfirm.setTenderId(ShiroUtil.getUserId());
        return ResultUtil.msg(clarifyClient.confirmClarify(clarifyConfirm));
    }

    @ApiOperation(value = "查看澄清/补疑", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "澄清补遗主键Id", value = "id", dataTypeClass = Long.class)
    })
    @PostMapping("/clarify/findClarifyById")
    public ResponseDto findClarifyById(@RequestBody ClarifyDTO clarifyDTO) {
        return ResultUtil.msg(clarifyClient.findClarifyById(clarifyDTO.getId()));
    }

    @ApiOperation(value = "查看澄清/补疑回执列表", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "澄清补遗主键Id", value = "id", dataTypeClass = Long.class)
    })
    @PostMapping("/clarify/pageClarifyConfirm")
    public ResponseDto pageClarifyConfirm(@RequestBody ClarifyDTO clarifyDTO) {
        Message<PageResult<ClarifyConfirmDTO>> clarifyConfirm = clarifyClient.pageClarifyConfirm(clarifyDTO);
        return ResultUtil.msg(clarifyConfirm);
    }

    @ApiOperation(value = "将澄清内容html片段转换为PDF", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "澄清内容", value = "content", dataTypeClass = Long.class)
    })
    @PostMapping("/clarify/clarifyHtmlToPDF")
    public ResponseDto clarifyHtmlToPDF(@RequestBody ClarifyDTO clarifyDTO) {
        // 功能完全一样，此接口只给澄清补遗使用
        String projectName = clarifyDTO.getProjectName();
        if (projectName == null){
            projectName = "";
        }
        String content = clarifyDTO.getContent();
        if (StrUtil.isEmpty(content)) {
            return ResultUtil.fail(MsgEnum.INCORRECT_PARAM.msg());
        }
        HTMLToPDFService htmlToPDFService = new HTMLToPDFService(persistenceService);
        String fileName = projectName + "澄清文件.pdf";
        // 文件上传OSS
        ResponseDto responseDto = htmlToPDFService.htmlToPDF(content, fileName);

        return responseDto;
    }


    @ApiOperation(value = "将澄清内容html片段转换为PDF", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "澄清内容", value = "content", dataTypeClass = Long.class)
    })
    @PostMapping("/clarify/htmlToPDF")
    public ResponseDto htmlToPDF(@RequestBody ClarifyDTO clarifyDTO) {
        String projectName = clarifyDTO.getProjectName();
        if(projectName == null){
            projectName = "";
        }
        String sectionName = clarifyDTO.getSectionName();
        if(sectionName == null){
            sectionName = "";
        }
        String content = clarifyDTO.getContent();
        if (StrUtil.isEmpty(content)) {
            return ResultUtil.fail(MsgEnum.INCORRECT_PARAM.msg());
        }
        //将澄清内容html片段转换为word文件流
        File wordFile = OfficeUtil.htmlStrToWordFile(content, null);
        File removeSpireDocWaterFile = OfficeUtil.removeSpireDocWater(wordFile);
        //再将word字节流转换为pdf字节流
        byte[] pdfContent = AsposeConvertUtil.wordToPDF(removeSpireDocWaterFile);
        //构建参数，上传至OSS文件服务器
//        File pdfFile  = FileUtil.writeBytes(pdfContent, new File(CommonConstant.TEMP_PATH + "/" + projectName + "澄清文件.pdf"));
        /**
         * zhanghu
         * 修改文件名称
         * 2022年3月8日
         */
        File pdfFile = FileUtil.writeBytes(pdfContent, new File(CommonConstant.TEMP_PATH + "/" + projectName + sectionName + "投标回执文件.pdf"));
        UploadEntity uploadEntity = new UploadEntity(pdfFile);
        List<HbFileInfo> fileInfoList = new ArrayList<>();
        try {
            fileInfoList = persistenceService.uploadServer(uploadEntity);
        } catch (IOException e) {
            log.error("澄清文件上传OSS服务器异常", e);
        }
        return ResultUtil.success(MsgEnum.SUCCESS.msg(), fileInfoList);
    }


    //-------------------------------------------- 供应商问题相关逻辑 -----------------------------------------

    @ApiOperation(value = "供应商提出问题", notes = "供应商提出问题", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "ProblemDto", value = "ProblemDto", dataTypeClass = ProblemDTO.class)
    })
    @PostMapping("/problem/saveProblem")
    public ResponseDto saveProblem(@RequestBody ProblemDTO problem) {
        LoginUser<Long> loginUser = ShiroUtil.getUser();
        if (null == loginUser) {
            return ResultUtil.fail(MsgEnum.LOGIN_EXPIRE);
        }
        problem.setTenderId(loginUser.getId());
        problem.setProposerId(loginUser.getId());
        ShiroUtil.fillOwner(problem);
        return ResultUtil.msg(clarifyClient.saveProblem(problem));
    }

    @ApiOperation(value = "供应商提出问题列表(投标人用)", notes = "供应商提出问题列表(投标人用)", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "供应商提出问题对象", value = "供应商提出问题对象", dataTypeClass = ProblemDTO.class)
    })
    @PostMapping("/problem/findProblemListBySectionId")
    public ResponseDto findProblemListBySectionId(@RequestBody ProblemDTO problem) {
        LoginUser<Long> loginUser = ShiroUtil.getUser();
        if (null == loginUser) {
            return ResultUtil.fail(MsgEnum.LOGIN_EXPIRE);
        }
        problem.setTenderId(loginUser.getId());
        problem.setProposerId(loginUser.getId());
        Message<PageResult<ProblemDTO>> problemList = clarifyClient.findProblemListBySectionId(problem);
        JSONObject extInfo = ShiroUtil.getExtInfo();
        if (extInfo == null) {
            return ResultUtil.msg(problemList);
        }
        String orgName = extInfo.get("orgName", String.class);
        if (problemList.isFail() || problemList.getData() == null) {
            return ResultUtil.msg(problemList);

        }
        PageResult<ProblemDTO> data = problemList.getData();
        if (CollUtil.isEmpty(data.getRecords())) {
            return ResultUtil.msg(problemList);
        }

        for (ProblemDTO record : data.getRecords()) {
            record.setOrgName(orgName);
        }
        return ResultUtil.msg(problemList);
    }

    @ApiOperation(value = "供应商发出问题", notes = "供应商发出问题", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "id", dataTypeClass = Long.class)
    })
    @SmsSend(type = 11)
    @PostMapping("/problem/sendOutProblem")
    public ResponseDto sendOutProblem(@RequestBody ProblemDTO problem) {
        Message message = clarifyClient.sendOutProblem(problem.getId());
        Message<Problem> problemMessage = clarifyClient.getProblem(problem.getId());
        if (problemMessage.isFail() || problemMessage.getData() == null) {
            return ResultUtil.msg(message);

        }
        Problem data = problemMessage.getData();
        if (!Integer.valueOf(1).equals(data.getType())) {
            return ResultUtil.msg(message);
        }
        JSONObjectProperty jsonEntity = new JSONObjectProperty();
        jsonEntity.putOpt("activeName","ClarifyList");
        //给招标人发送审核消息
        SendNewsUtil.sendTendereeNews(
                data.getSectionId(),
                NewsTypeEnum.OBJECTION_QUESTION,
                NewsTypeTwoEnum.TENDEREEFILING_QUESTION,
                null,
                "/projectconsole",
                jsonEntity
        );
        return ResultUtil.msg(message);
    }

    @ApiOperation(value = "供应商提出问题列表(招标人用)", notes = "供应商提出问题列表(招标人用)", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "供应商提出问题对象", value = "供应商提出问题对象", dataTypeClass = ProblemDTO.class)
    })
    @PostMapping("/problem/findBiddingProblemListBySectionId")
    public ResponseDto findBiddingProblemListBySectionId(@RequestBody ProblemDTO problem) {
        return ResultUtil.msg(clarifyClient.findBiddingProblemListBySectionId(problem));
    }

    @ApiOperation(value = "招标人回复问题", notes = "招标人回复问题", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "ProblemDto", value = "ProblemDto", dataTypeClass = ProblemDTO.class)
    })
    @PostMapping("/problem/replyProblem")
    public ResponseDto replyProblem(@RequestBody ProblemDTO problem) {
        LoginUser<Long> loginUser = ShiroUtil.getUser();
        if (null == loginUser) {
            return ResultUtil.fail(MsgEnum.LOGIN_EXPIRE);
        }
        problem.setProposerId(loginUser.getId());
        problem.setProposerName(ShiroUtil.getUser().getFullName());
        ShiroUtil.fillOwner(problem);

        Message message = clarifyClient.replyProblem(problem);
        Message<Problem> problemMessage = clarifyClient.getProblem(problem.getId());
        if (problemMessage.isFail() || problemMessage.getData() == null) {
            return ResultUtil.msg(message);

        }
        Problem data = problemMessage.getData();
        //给投标人发消息
        SendNewsUtil.sendBiddereeNews(
                data.getSectionId(),
                NewsTypeEnum.OBJECTION_QUESTION,
                NewsTypeTwoEnum.BIDDER_QUESTION,
                null,
                null,
                "/console/clarify/bidder",
                CollUtil.list(false, data.getProposerId())
        );
        return ResultUtil.msg(message);
    }

    @ApiOperation(value = "投标人回执问题", notes = "投标人回执问题", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "ProblemDto", value = "ProblemDto", dataTypeClass = ProblemDTO.class)
    })
    @PostMapping("/problem/receiptProblem")
    public ResponseDto receiptProblem(@RequestBody ProblemDTO problem) {
        LoginUser<Long> loginUser = ShiroUtil.getUser();
        if (null == loginUser) {
            return ResultUtil.fail(MsgEnum.LOGIN_EXPIRE);
        }
        problem.setTenderId(loginUser.getId());
        ShiroUtil.fillOwner(problem);
        return ResultUtil.msg(clarifyClient.receiptProblem(problem));
    }

    @ApiOperation(value = "查看问题", notes = "查看问题", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "id", dataTypeClass = Long.class)
    })
    @PostMapping("/problem/findProblem")
    public ResponseDto findProblem(@RequestBody ProblemDTO problem) {
        return ResultUtil.msg(clarifyClient.findProblem(problem.getId()));
    }

    /**
     * @Description: 查询投标人澄清回执word模版需要的信息
     *
     * { 澄清代理公司、 项目名称、 当前时间(xxxx年xx月xx日)、 回执企业 }
     *
     * @author yuezheng
     * @param
     * @return org.fzzn.core.model.msg.ResponseDto
     * @date 2022/5/23 13:48
     */
    @PostMapping("/clarify/template")
    public ResponseDto findClarifyTemplateInfo(@RequestBody ClarifyDTO clarifyDTO) {
        Message<ClarifyTemplateDTO> clarifyTemplateInfo = clarifyClient.findClarifyTemplateInfo(clarifyDTO);
        OrgDTO orgDTO = orgClient.getOrgById(ShiroUtil.getOrgId()).getData();
        ClarifyTemplateDTO result = clarifyTemplateInfo.getData();
        result.setOrgName(orgDTO.getOrgName());
//        clarifyTemplateInfo.setData(result);
        return ResultUtil.msg(clarifyTemplateInfo);
    }
}
